import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

let renderer, scene, camera, controls
let uniforms1 = {
    u_time: { value: 0.0 }
}
let vertexShader = `
varying vec2 vUv;
attribute float percent;
uniform float u_time;
uniform float number;
uniform float speed;
uniform float length;
varying float opacity;
uniform float size;
void main()
{
    vUv = uv;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    float l = clamp(1.0-length,0.0,1.0);
    gl_PointSize = clamp(fract(percent*number + l - u_time*number*speed)-l ,0.0,1.) * size * (1./length);
    opacity = gl_PointSize/size;
    gl_Position = projectionMatrix * mvPosition;
}
`
let fragmentShader = `
#ifdef GL_ES
precision mediump float;
#endif
varying float opacity;
uniform vec3 color;
void main(){
    if(opacity <=0.2){
        discard;
    }
    gl_FragColor = vec4(color,1.0);
}
`

function init() {
    initRenderer()
    initScene()
    initCamera()
    initControls()
    initHelp()
    initLine()
    animate()
}

function initRenderer() {
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false })
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(document.getElementById('webgl-output').clientWidth, document.getElementById('webgl-output').clientHeight)
    document.getElementById('webgl-output').appendChild(renderer.domElement)
}
function initScene() {
    scene = new THREE.Scene()
}
function initCamera() {
    camera = new THREE.PerspectiveCamera(45, document.getElementById('webgl-output').clientWidth / document.getElementById('webgl-output').clientHeight, 0.1, 1000)
    camera.position.set(50, 50, -50);
    camera.lookAt(scene.position)
}
function initLine() {
    let v3ps = [new THREE.Vector3(20, 0, 20), new THREE.Vector3(0, 20, 0), new THREE.Vector3(-20, 0, -20)]
    let curve = new THREE.CatmullRomCurve3(v3ps)

    var points = curve.getPoints(10000)
    var geometry = new THREE.BufferGeometry().setFromPoints(points)
    const length = points.length

    var percents = new Float32Array(length)
    for (let i = 0; i < points.length; i += 1) {
        percents[i] = (i / length)
    }
    geometry.setAttribute('percent', new THREE.BufferAttribute(percents, 1))
    const singleUniforms = {
        u_time: uniforms1.u_time,
        number: { type: 'f', value: 2 },//控制几条流动的线
        speed: { type: 'f', value: 0.4 },
        length: { type: 'f', value: 0.2 },
        size: { type: 'f', value: 4 },
        color: { type: 'v3', value: new THREE.Color('#18ff00') }
    }

    let lineMaterial = new THREE.ShaderMaterial({
        uniforms: singleUniforms,
        vertexShader: vertexShader,
        fragmentShader: fragmentShader,
        transparent: true,
        side: THREE.DoubleSide,
        blending: THREE.AdditiveBlending
    })

    var flyLine = new THREE.Points(geometry, lineMaterial)
    const lineGeometry = new THREE.BufferGeometry()
    lineGeometry.setFromPoints(curve.getPoints(1000))

    let line = new THREE.Line(lineGeometry, new THREE.LineBasicMaterial({ color: 0xffffff }))
    scene.add(line)
    scene.add(flyLine)
}
function initHelp() {
    let axes = new THREE.AxesHelper(1000)
    scene.add(axes)
}
function initControls() {
    controls = new OrbitControls(camera, renderer.domElement)
}
function animate() {
    renderer.render(scene, camera)
    uniforms1.u_time.value += 0.007
    requestAnimationFrame(animate)
}
export default {
    init
}